/*
 * Copyright 2007-2008 Andrew O'Malley
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package ws.quokka.plugin.jetty;

import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.resources.FileResource;

import org.mortbay.jetty.plus.annotation.InjectionCollection;
import org.mortbay.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.mortbay.jetty.plus.annotation.RunAsCollection;
import org.mortbay.jetty.plus.webapp.Configuration;
import org.mortbay.jetty.servlet.FilterHolder;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.jetty.webapp.WebAppClassLoader;

import org.mortbay.log.Log;

import org.mortbay.util.LazyList;

import java.io.File;
import java.io.IOException;

import java.lang.reflect.Method;

import java.net.URL;

import java.util.Iterator;


/**
 *
 */
public class PlusConfiguration extends Configuration {
    //~ Methods --------------------------------------------------------------------------------------------------------

    public void configureClassLoader() throws Exception {
        for (Iterator i = getContext().getClassPathFiles().iterator(); i.hasNext();) {
            FileResource fileResource = (FileResource)i.next();
            WebAppClassLoader loader = (WebAppClassLoader)getWebAppContext().getClassLoader();
            loader.addClassPath(fileResource.getFile().getCanonicalPath());
        }
    }

    protected URL findWebXml() throws IOException {
        // If an explicit web.xml file has been set (eg for jetty:run) then use it
        if ((getContext().getWebXmlFile() != null) && getContext().getWebXmlFile().exists()) {
            return getContext().getWebXmlFile().toURI().toURL();
        }

        // Uf we haven't overridden location of web.xml file, use the standard way of finding it
        return super.findWebXml();
    }

    private PluginWebAppContext getContext() {
        return (PluginWebAppContext)getWebAppContext();
    }

    public void parseAnnotations() throws Exception {
        String v = System.getProperty("java.version");
        String[] version = v.split("\\.");

        if (version == null) {
            Log.info("Unable to determine jvm version, annotations will not be supported");

            return;
        }

        int major = Integer.parseInt(version[0]);
        int minor = Integer.parseInt(version[1]);

        if ((major >= 1) && (minor >= 5)) {
            //TODO it would be nice to be able to re-use the parseAnnotations() method on
            //the org.mortbay.jetty.annotations.Configuration class, but it's too difficult?
            //able to use annotations on on jdk1.5 and above
            Class annotationParserClass = Thread.currentThread().getContextClassLoader().loadClass("org.mortbay.jetty.annotations.AnnotationParser");
            Method parseAnnotationsMethod = annotationParserClass.getMethod("parseAnnotations",
                    new Class[] {
                        Class.class, RunAsCollection.class, InjectionCollection.class, LifeCycleCallbackCollection.class
                    });

            //look thru _servlets
            Iterator itor = LazyList.iterator(_servlets);

            while (itor.hasNext()) {
                ServletHolder holder = (ServletHolder)itor.next();
                Class servlet = getWebAppContext().loadClass(holder.getClassName());
                parseAnnotationsMethod.invoke(null, new Object[] { servlet, _runAsCollection, _injections, _callbacks });
            }

            //look thru _filters
            itor = LazyList.iterator(_filters);

            while (itor.hasNext()) {
                FilterHolder holder = (FilterHolder)itor.next();
                Class filter = getWebAppContext().loadClass(holder.getClassName());
                parseAnnotationsMethod.invoke(null, new Object[] { filter, null, _injections, _callbacks });
            }

            //look thru _listeners
            itor = LazyList.iterator(_listeners);

            while (itor.hasNext()) {
                Object listener = itor.next();
                parseAnnotationsMethod.invoke(null, new Object[] { listener.getClass(), null, _injections, _callbacks });
            }
        } else {
            Log.info("Annotations are not supported on jvms prior to jdk1.5");
        }
    }
}
